perm filename SEC3.TEX[105,CSD] blob sn#536188 filedate 1980-09-19 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00017 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00003 00002	%\sneakhead{Programming Superstitions} \sendindex{Superstitions}
C00005 00003	\specialbegin{Storage Variables and Assignment} \sendindex{Storage Variables} \sendindex{Assignment}
C00010 00004	     In a program, a command which, when executed, gives the storage variable
C00016 00005	%This is INSERT E
C00017 00006	%This is INSERT G
C00019 00007	%This is INSERT L %after conditionals 
C00020 00008	\specialbegin{Reading} \sendindex{Reading}
C00027 00009	%This is INSERT I
C00030 00010	%This is INSERTC
C00035 00011	\vfill\eject  %This is INSERT J
C00040 00012
C00041 00013	%This is INSERT A
C00049 00014	\specialbegin{Conditional Commands} \sendindex{Conditional Commands}
C00062 00015	%This is INSERT M %for notes-after section on conditional commands
C00066 00016	%This is INSERT K
C00068 00017	\exercise
C00075 ENDMK
C⊗;
%\sneakhead{Programming Superstitions} \sendindex{Superstitions}

%     The novice programmer will often find the behavior of his program
%difficult to diagnose.  Experimentation may be helpful in leading him to
%discover where he misinterpreted the rules and definitions of the language.
%He should however be extremely cautious about deciding that the real rules
%of the language are different from those he has been told.  Almost invariably
%this decision would be wrong.  He would do better to take his difficulty to a
%member of the teaching staff or to an experienced Pascal programmer.

\specialbegin{Storage Variables and Assignment} \sendindex{Storage Variables} \sendindex{Assignment}

The harmonic numbers are:

$$\eqalign{H↓1 ⊗= 1\cr
           H↓2 ⊗= 1 +  {1\over2}\cr
           H↓3 ⊗= 1 +  {1\over2} + {1\over3}\cr
           H↓4 ⊗= 1 +  {1\over2} + {1\over3} + {1\over4}, etc.\cr}$$

In mathematical language, $$H↓n = {\sum↓{j=1}} {1\over j}$$

Evaluation of this series seems to be a natural candidate for iteration,
decomposing the problem
\wuncode{print the first 100 harmonic numbers}
into

\startcode
        FOR J:=1 TO 100 DO
            print the J-th harmonic number
\endcode

However, here we are stuck, even if we realize that $H↓j = H↓{j-1} + 1/j$, 
and that we have just printed  $H↓{j-1}$ at the time we want $H↓j, (j ≥ 2)$.
Let us, however, go as far as we can, making a special case of $H↓{1}$, because it
can not be computed from its predecessor.

\startcode
        Print $H↓1$
        FOR J:= 2 TO 100 DO
        Print (1/J) + (the number most recently printed)
\endcode

What is needed here is a mechanism for saving the results of previous
computations.  For this purpose, Pascal provides the ability to use variables
which hold the values resulting from previous computations.  They are not
analogous to the variables of mathematics, which denote a single,
unknown value, which does not ``vary'' at all; nor to the iteration variables,
which run through a preordained set of values.  We shall call them
{\sl storage variables}, \sendindex{storage variables} and a program may 
change their values whenever desired.
We shall use upper case letters for storage variables and lower case letters
for mathematical variables.

     We modify the above program by using a variable,  {\tt SUM},
whose value will be changed as needed to remain
equal to the number most recently printed.  We use comments extensively to
explain the significance of the information kept as the value of a variable.

     Pascal requires that each storage variable used be explicitly created by
a special kind of command called a {\sl declaration}. \sendindex{declaration}
The declaration
\wuncode{VAR SUM : REAL} \sendindex{REAL}
creates a variable  {\tt SUM}  which is permitted to take any number as its value.
(``Real'' is used here in the sense, ``not imaginary''.  What mathematicians
call real numbers are what the rest of us call numbers.)  We might also have
occasion to declare
\wuncode{VAR A :INTEGER} \sendindex{INTEGER}
to create a variable  {\tt A}  which could take on only whole-number values,
whether positive, negative, or zero.  (There are pragmatic reasons for having
several types of storage variables; the more restricted types, such as the
integer variables, typically require less of the computer's memory resources
for their representation, and the operations of arithmetic can often be
performed on them more rapidly.)

     In a program, a command which, when executed, gives the storage variable
$\Vscr$  the value of the expression  $\Escr$, is written
\wuncode{$\Vscr$:=$\Escr$}
which can be read ``assign the value of the expression  $\Escr$ to the variable
$\Vscr$,''
or simply ``Set $\Vscr$ equal to $\Escr$.''  Such a command is called an
{\sl assignment}. \sendindex{assignment}
(If $\Vscr$ is an integer variable, $\Escr$ must be an integer expression.  If
$\Vscr$ is a real variable, $\Escr$ may be either a real or an integer expression.)

Our program, as modified, now becomes

\startcode
    PROGRAM HARMONICNUMBERS;
\sendnotes{RWF==>Cannot join to one line.Line would too long for TEX}
       (* SUM WILL TAKE ON THE VALUES OF THE HARMONIC NUMBERS
                                 H(1),$\ldotss$,H(100) *)
       (* THE N-TH HARMONIC NUMBER H(N) = 1 + 1/2 + 1/3 + $\ldots$ + 1/N *)
    VAR  SUM : REAL; 
         J : INTEGER;
    BEGIN
    Give SUM the value 1 (= H$↓{1}$) and print H$↓{1}$;
    FOR J:=2 TO 100 DO
        (*  SUM = H(J-1) *)
        (Take (1/J) + the old value of SUM (= H$↓{J-1}$) as the
           new value for SUM (= H$↓{J}$) and print SUM.)
    END.
\endcode

We decompose
\wuncode{give SUM the value 1 and print H$↓{1}$;}
into
\startcode
        SUM:= 1;
        WRITELN(SUM);
\endcode

\noindent
and we change

\startcode
        Take (1/j) + the old value of SUM (= H$↓{j-1}$) as
           the new value for SUM (= H$↓{j}$) and print SUM
\endcode

\noindent
to
\startcode
        BEGIN
        SUM := 1/j + SUM;
        WRITELN(SUM)
        END
\endcode

\noindent
Our program is now

\startcode
        PROGRAM HARMONICNUMBERS;  
        (* SUM TAKES ON THE VALUES OF THE HARMONIC NUMBERS H(1),$\ldotss$,H(100) *)
        (* THE N-TH HARMONIC NUMBER H(N) = 1 + 1/2 + 1/3 + $\ldots$ + 1/N *)
        VAR SUM : REAL;  
              J : INTEGER ;
        BEGIN
        SUM:= 1;
        WRITELN(SUM);
        FOR J:= 2 TO 100 DO
           (*  SUM = H(J-1) *)
              BEGIN
              SUM:= 1/J + SUM;
              WRITELN(SUM)
              END
        END.
\endcode

\sendindex{storage variables} is
The general form of declarations which create storage variables

\startcode
     VAR $\Iscr↓{11},\Iscr↓{21},\ldotss,\Iscr↓{n1}$ : $\Tscr↓1$;
         $\Iscr↓{12},\Iscr↓{22},\ldotss,\Iscr↓{n2}$ : $\Tscr↓2$;
             .
             .
             .
         $\Iscr↓{1m},\Iscr↓{2m},\ldotss,\Iscr↓{nm}$ : $\Tscr↓m$;
\endcode

\noindent
where  $\Tscr$  is the {\sl type} \sendindex{type} of value which the variables  
$\Iscr↓{1},\Iscr↓{2},\ldots,\Iscr↓{n}, (n ≥ 1)$
take on.  In addition to the types {\tt INTEGER} \sendindex{INTEGER} 
and {\tt REAL}, \sendindex{REAL} we shall encounter others.

     The reader should assume for the moment that all declarations must be
written at the beginning of the program, just after the header list, separated
by semicolons.  {\tt VAR} \sendindex{VAR} is not repeated (see above example).
\rule{
For every storage variable, include a comment explaining what that variable does,
and, if necessary, why and how it does it.
}

%This is INSERT E
%\vfill  %BUG.  This produces a blank page.  Why?
\example
\startcode
(* Summing the first 100 perfect squares. *)

PROGRAM SUMSQUARES (OUTPUT);
VAR  I,                         (* ITERATION VARIABLE *)
     SUM : INTEGER;             (* SUM OF FIRST I PERFECT SQUARES *)

BEGIN
SUM := 0;
FOR I := 1 TO 100 DO
   SUM := SUM + SQR(I);
   WRITELN ('SUM OF FIRST 100 PERFECT SQUARES : ', SUM)
END.
\endcode

\topoutput
SUM OF FIRST 100 PERFECT SQUARES :       338350
\botoutput
%End of INSERT E
%This is INSERT G
\sendnotes{FINALCHECK: eject inserted to eliminate widow in 9/18 version.}
\vfill\eject
\example
\startcode
(* This program prints out a triangle of consecutive integers *)

PROGRAM TRIANGLE ( OUTPUT ) ;
VAR     LINE ,                          (* LINENUMBER *)
        COLUMN ,                        (* COLUMNNUMBER *)
        COUNTER       : INTEGER ;       (* CURRENT NUMBER TO BE PRINTED *)
BEGIN
(* INITIALIZATION *)
COUNTER := 0 ;
(* PRINT TRIANGLE *)
FOR LINE := 1 TO 10 DO
    BEGIN                       (* PRINT ONE LINE *)
    FOR COLUMN := 1 TO LINE DO
        BEGIN                   (* PRINT ONE NUMBER *)
        COUNTER := COUNTER + 1 ;
        WRITE ( COUNTER:3 )
        END ;
    WRITELN
    END
END.
\endcode

\penalty500
\topoutput
  1
  2  3
  4  5  6
  7  8  9 10
 11 12 13 14 15
 16 17 18 19 20 21
 22 23 24 25 26 27 28
 29 30 31 32 33 34 35 36
 37 38 39 40 41 42 43 44 45
 46 47 48 49 50 51 52 53 54 55
\botoutput
%END OF INSERT G

\vfill
\eject
%This is INSERT L %after conditionals 
\exercise
What does this program draw?

\startcode
PROGRAM P ;
VAR  S, A, DS, DA, L, C  : INTEGER ;

BEGIN
S := 24 ;
A := 1 ;
DS := $-$1 ;
DA := 2 ;
FOR L := 0 TO 48 DO
    BEGIN
    FOR C := 1 TO S DO WRITE(' ') ;
    FOR C := 1 TO A DO WRITE('*') ;
    WRITELN ;
    IF L = 24 THEN
        BEGIN
        DS := 1 ;
        DA := $-$2
        END ;
    S := S + DS ;
    A := A + DA
    END
END .

\endcode

\endexercise
%End of INSERT L
\specialbegin{Reading} \sendindex{Reading}



     The programs we have seen until now have each been capable of only a
single computation.  To enable a program to solve a different problem each time
it is used, we have to provide it with different information each time it is
run.  This information can be obtained from a file, or from the program's user
at his terminal.  To get a number from the file called {\tt INPUT}, and assign
it to variable {\tt X}, use the command
\wuncode{READ(INPUT,X)}
or equivalently
\wuncode{READ(X)}
To get a number from the user at the terminal, and assign it to {\tt X}, use the
command
\wuncode{READ(TTY,X)}
where TTY (an abbreviation for teletype) is the Pascal name of the terminal.  
When  this command is executed, the program will wait for the user to type in the
required number, including a space or carriage return to end it.

        A program to take a number from the input file, and print it along
with its square root, might be

\startcode
        PROGRAM SQUAREROOT;
        VAR X:REAL;
        BEGIN
        READ(X);
        WRITELN(X, SQRT(X))
        END.
\endcode

        A similar program, taking the number from the terminal, could be 
obtained by using the command
\wuncode{READ(TTY,X)}
However, this program would do nothing to tell the user that it was waiting 
for him to type something, nor what it needed.  A better program would first 
print a message describing the desired input, and then execute a {\tt BREAK(TTY)} 
command (which makes the program complete all terminal output before taking any input).  
The complete program might be:

\startcode
        PROGRAM SQUAREROOT;
           VAR X:REAL;
        BEGIN
        WRITELN(TTY,'ENTER POSITIVE NUMBER FOR SQUARE ROOT');
        BREAK(TTY);
        READ(TTY, X);
        WRITELN (X, SQRT(X))
        END.
\endcode

\noindent
When this program is run, the program types
\wuncode{ENTER POSITIVE NUMBER FOR SQUARE ROOT}
If the user then types 2, followed by a {\tt RETURN}, the program puts
\wuncode{2     1.414214}
in the output file.

     Usually, a program will need several pieces of information from the user.
It is usually advisable for the program to print a request for each, before
executing a read command.  (This is called {\sl prompting} \sendindex{prompting}
the user.)  A program to get two numbers, printing the square root of the first
and the square of the second, might be:

\startcode
      PROGRAM P;
      (declarations)
      BEGIN
      WRITELN(TTY, 'SQUARE ROOT OF'); (* OUTPUT TO TERMINAL *)
      BREAK(TTY);
      READ (TTY, X);
      WRITELN('SQUARE ROOT OF', X, '=', SQRT(X)); (* OUTPUT TO FILE *)
      WRITELN (TTY, 'SQUARE OF');  (* OUTPUT TO TERMINAL *)
      BREAK(TTY);
      READ (TTY, X);
      WRITELN ('SQUARE OF', X, '=', X*X)  (* OUTPUT TO FILE *)
      END
\endcode

Alternatively, to present results at the terminal, the second and fourth
{\tt WRITELN} \sendindex{WRITELN} commands could be changed to
\wuncode{WRITELN (TTY, '=', SQRT (X));}
and
\wuncode{WRITELN (TTY, '=', X*X).}
When this second version of the program is executed, the results printed 
at the terminal might be

\topoutput
        SQUARE ROOT OF  
        2
        = 1.414214
        SQUARE OF  
        11
        = 121
\botoutput

\noindent
where the user typed the {\tt 2} and {\tt 11}, the rest being printed by the
program. 

        It is important that a program to be used from a terminal should 
{\sl prompt} the user with a description of each desired datum. 
It is also important to include all input data in the output file, to confirm 
the correctness of the data entry.

\rule{
An explanatory prompt should precede all terminal input operations.
It should be clear to a user who does not know the program details.
All input data should appear in the output file.  This is done to protect
against the possibility that the user made a typing error.  Such a repetition
of input in the output is called an {\sl echo}. \sendindex{echo}
}

%This is INSERT I
\sendnotes{FINALCHECK: eject inserted to eliminate widow 9/18.}
\vfill\eject
\example
\startcode
(* A PROGRAM TO COMPUTE AND PRINT THE RUNNING BALANCE OF A BANK      *)
(*  ACCOUNT.                                                         *)
(*  INPUT    :  THE NUMBER OF CHECKS TO BE ENTERED IN THE BALANCE    *)
(*              THE INITIAL BALANCE                                  *)
(*              THE AMOUNT OF EACH INDIVIDUAL CHECK                  *)
%p8e1 goes here

PROGRAM BALANCE ( INPUT* , OUTPUT ) ;
VAR     I,
        COUNT    :  INTEGER ;     (* NUMBER OF CHECKS *)
        CHECK,                    (* AMOUNT OF A CHECK *)
        BALANCE  :  REAL ;        (* BALANCE OF ACCOUNT *)
BEGIN
(* READ INITIAL DATA *)
READ ( COUNT ) ;
READ (BALANCE ) ;
(* PRINT INITIAL DATA AND HEADER *)
WRITELN (' INITIAL BALANCE       :',BALANCE:8:2 ) ;
WRITELN (' NUMBER OF CHECKS      :',COUNT:5 ) ;
WRITELN ;
WRITELN (' CHECK NO.    AMOUNT      BALANCE' ) ;
WRITELN ('---------------------------------' ) ;
(* PROCESS THE CHECKS *)
FOR I := 1 TO COUNT DO
    BEGIN 
    READ ( CHECK ) ;
    BALANCE := BALANCE - CHECK  ;
    WRITELN ( I:10 , CHECK:10:2 , BALANCE:12:2 )
    END
END.

\startcode
Input  :
--------
4
234.60
125.00
4.50
61.05
5.00
\endcode

\topoutput
INITIAL BALANCE        :  234.60
NUMBER OF CHECKS       :    4

CHECK NO.    AMOUNT       BALANCE
---------------------------------
        1    125.00        109.60
        2      4.50        105.09
        3     61.05         44.05
        4      5.00         39.05
\botoutput
%This is the end of INSERT I
%This is INSERTC
\example
\sendnotes{RWF==> end of definite iteration?}
Write a Pascal program to read from a file the coefficients of a polynomial, and a 
point at which to evaluate it, and print out the result of the evaluation.  A
line in the file like
$$3.0\quad2\quad4.0\quad5.0\quad6.0$$

\noindent
designates the polynomial  $4x↑2 + 5x + 6$ with  $x = 3$, giving an answer of $57$;
while
$$2.3\quad 4\quad  1.2\quad -3.4\quad 4.5\quad 0.0\quad 6.7$$

\noindent
calls for  $1.2x↑4 $-$ 3.4x↑3 + 4.5x↑2 + 6.7$  where  $x = 2.3$ (about $22.7$).  The
second number in each specification is the degree of the polynomial, and it is
followed by (degree $+ 1$) coefficients (including explicit zeroes, if any).  All
of these numbers are in {\tt REAL} format, except for the degree, which is an
{\tt INTEGER}.  The complete file consists of an integer telling how many such
lines there are, followed by the lines themselves.  For example:

\startcode
40
3.0   2   4.0    5.0   6.0
2.3   4   1.2   -3.4   4.5   0.0   6.7
{\rm thirty-eight more lines}
\endcode

To make the program as versatile as possible, you should use the following 
approach (based on Horner's rule):  Note that  $$Ax↑3 + Bx↑2 + Cx + D = 
(((Ax) + B)x + C)x + D;$$ in general:

$$\twoline{R↓nx↑n + R↓{n-1}x↑{n-1} + \cdotss + R↓2x↑2 + R↓1x + R↓0}{2pt}{\null =
(\cdotss(((R↓nx) + R↓{n-1})x + R↓{n-2})x + \cdotss + R↓1)x + R↓0 .}$$

\noindent
This suggests a method of evaluating the polynomial on the fly, as the coefficients
are being read in:  repeatedly calculate a new result by taking the old result, 
multiplying by $x$ and adding the new coefficient,   This, correctly
programmed, works for polynomials of any degree, including zero.

The output should include a reasonable facsimile of the input polynomial as
well as the result.  For instance the output for the two lines above might be:

\startcode
        ( 4.0 X$\up$2 + 5.0 X$\up$1 + 6.0 )  AT  X=30  IS  56.9
        ( 1.2 X$\up$4 + -3.4 X$\up$3 + 4.5 X$\up$2 + 0.0 X$\up$1 + 6.7 )  AT  X=2.3  IS  22.7
\endcode

\noindent
To print a {\tt REAL} number, {\tt R}, neatly (i.e. without an exponent,
and with a specified number of digits to the right of the decimal point), you
might try:
\wuncode{WRITE(R:TRUNC(LOG(ABS(R)+1))+3+DP:DP)}
where {\tt DP} is the number of decimal places you want displayed (one should
be enough for this assignment). 

%rewrite
\sendnotes{Professor Floyd to rewrite this part later}.

That says ``write out {\tt R} with just enough room for the sign, all the digits to
the left of the decimal point, the decimal point itself, and {\tt DP} places to
the right of the decimal point.''  You may find your answers off by one in the
least significant place, due to rounding errors.  Also, the ``$\up$'' character
may look more like ``{\tt ∂}'' on your terminal and/or printout.

%This is the end of INSERT C
\vfill\eject  %This is INSERT J
\startcode
(* EVALUATION OF POLYNOMIALS USING HORNER'S RULE. *)
(*  INPUT : FIRST LINE : NUMBER OF POLYNOMIALS TO BE EVALUATED *)
(*          NEXT LINES  :  X DEGREE COEF COEF COEF ... COEF *)
(*                           X       :  POINT OF EVALUATION *)
(*                           DEGREE  :  DEGREE OF POLYNOMIAL*)
(*                           COEF    :  POLYNOMIAL COEFFICIENTS FROM *)
(*                                      HIGH ORDER TO LOW ORDER      *)
(*  OUTPUT  :  FACSIMILE OF INPUT , EVALUATED POLYNOMIAL *)

PROGRAM POLYEVAL ( INPUT* , OUTPUT ) ;
CONST   DP      = 1 ;         (* NUMBER OF DECIMAL PLACES IN OUTPUT *)
VAR     NUMBER,               (* NUMBER OF POLYNOMIALS *)
        DEGREE,               (* DEGREE OF POLYNOMIAL  *)
        I, J    :  INTEGER ;  (* ITERATION VARIABLES   *)
        X,                    (* EVALUATION POINT      *)
        COEF,                 (* POLYNOMIAL COEFFICIENT*)
        VALUE   :  REAL ;     (* (RUNNING) VALUE OF POLYNOMIAL IN X *)
\allowbreak
BEGIN
(* READ NUMBER OF LINES *)
READ ( NUMBER ) ;
(* EVALUATE NUMBER POLYNOMIALS *)
FOR I := 1 TO NUMBER DO
    BEGIN     (* INITIAL INPUT-OUTPUT AND INITIALIZATION OF VALUE *)
    READ ( X, DEGREE ) ;
    WRITE ( '( ' ) ;
    VALUE := 0.0 ;
    (* EVALUATE POLYNOMIAL *)
    FOR J := DEGREE DOWNTO 0 DO
        BEGIN (* READ/WRITE ONE COEFFICIENT, AND APPLY ONE STEP OF
                 OF HORNER'S RULE *)
        READ ( COEF ) ;
        WRITE ( COEF:TRUNC(LOG(ABS(COEF)+1))+3+DP:DP ) ;
        IF J <> 0 THEN WRITE ( ' X∂', J:1, ' + ' ) ;
        VALUE  := VALUE*X + COEF
        END ; (* J ITERATION *)
    (*FINAL OUTPUT *)
    WRITELN ( ' )  AT X = ' , X:TRUNC(LOG(ABS(X)+1))+3+DP:DP,
              ' IS ' , VALUE:TRUNC(LOG(ABS(VALUE)+1))+3+DP:DP )
    END (* I ITERATION *)
END. (* POLYEVAL *)
\endcode
\vfill
\topoutput
( 4.0 X∂2 +  5.0 X∂1 +  6.0 ) AT X =  3.0 IS  56.9
( 1.2 X∂4 + -3.4 X∂3 + 4.5 X∂2 + 0.0 X∂1 + 6.6 ) AT X = 2.3 IS 22.7
( 1.0 X∂1 + 0.0 ) AT X = 0.0 IS 0.0
( 0.0 X∂2 + 0.0 X∂1 + 0.1 ) AT X = 999.0 IS 1008.2
( 1.0 X∂5 + -1.0 X∂4 + 1.0 X∂3 + -1.0 X∂2 + 1.0 X∂1 + -1.0 ) AT X = 0.0
       IS -0.9
( 1.0 X∂5 + -1.0 X∂4 + 1.0 X∂3 + -1.0 X∂2 + 1.0 X∂1 + -1.0 ) AT X = 200.0
       IS  318407961726.1
( 1.0 X∂5 + -1.0 X∂4 + 1.0 X∂3 + -1.0 X∂2 + 1.0 X∂1 + -1.0 ) AT X = 2.0
       IS  20.9
( -324.2 X∂2 + 5123.8 X∂1 + 0.0 ) AT X = 1234.5 IS -487799942.4
( 3.3 X∂2 + 6.6 X∂1 + 10.0 ) AT X = 0.3 IS 12.5
( -222.9 ) AT X = 284.7 IS -222.9
( -222.9 X∂1 + -223.0 ) AT X = 284.7 IS -63824.3
( -222.9 X∂2 + 334.0 X∂1 + -444.9 ) AT X = 284.7 IS -17981683.3
\botoutput
%This is the end of INSERT J

\exercise
Write a program which prints a rectangle of asterisks after reading its
height and width.  Use prompting and echoes.
\endexercise

\exercise
Write a program to add a series of numbers from the terminal,
printing the cumulative sums.  The set of numbers to be added should be
preceded by a number giving the size of the set.  Use prompting and echoes.
\endexercise
%This is INSERT A
\specialbegin{LOTS Pascal Note} 
\sendindex{LOTS}

        A Pascal program, by its {\tt WRITE} and {\tt WRITELN} commands,
sends numbers and characters to files in a form suitable for printing.  If
no explicit names are given to these files, it is assumed that
all output goes to one file which is called {\tt OUTPUT}.  This has a 
disadvantage.  If my last program left its results in the file called
{\tt OUTPUT}, and my current program writes its results there, I will
thereby lose the older results.  Furthermore, naming the file
{\tt OUTPUT} gives no hint of what the results are about.  And if I run
the same program again with different input, the new results replace and 
destroy the old ones.

        It is desirable to be able to name, each time the program is
run, the LOTS file which receives the results of your program.  In its 
simplest form,                                                          
to do this one writes the first line of the program in the form

\wuncode{PROGRAM $\Iscr$(OUTPUT);}

\noindent
where $\Iscr$ is the name of the program.  When the program is executed, it
will begin by asking the user at the terminal to provide the filename (in
a LOTS directory) for the output file.

        A Pascal program may write information in several different files,
each time it is run.  Each such file generally has two names: in Pascal
that name by which it is known to the program, a name which is built into the
program; and that name by which it is known to TOPS-20, a name provided
when the program is executed.  We shall call these names the Pascal name and
the directory name of the file, respectively.  Most Pascal names appear 
explicity in the first line of the program, in the form

\wuncode{PROGRAM $\Iscr↓0 (\Iscr ↓1, \Iscr ↓2, \ldotss, \Iscr ↓n)$;}

\noindent
where $\Iscr↓0$ is the name of the program, and $\Iscr↓1, \Iscr↓2, \ldotss, \Iscr↓n$
are the Pascal names of the files it uses.  They also appear explicitly in 
{\tt WRITE} and {\tt WRITELN} commands;

\wuncode{WRITE($\Iscr, \Escr$)}

\noindent
writes the value of expression $\Escr$ to the file with Pascal name $\Iscr$.

\samecode{
WRITE($\Iscr,\Escr↓1,\Escr↓2,\ldotss,\Escr↓n$)⊗WRITE($\Iscr,\Escr↓1$);\cr
\qquad ⊗ WRITE($\Iscr,\Escr↓2$);\cr
⊗\qquad .\cr
⊗\qquad .\cr
⊗\qquad .\cr
\qquad ⊗ WRITE($\Iscr, \Escr↓n$)\cr\noalign{\vskip 6pt}
WRITELN($\Iscr,\Escr↓1,\Escr↓2\ldotss,\Escr↓n$)⊗WRITE($\Iscr,\Escr↓1,\Escr↓2,\ldotss,\Escr↓n$);\cr
\qquad ⊗WRITELN($\Iscr$)\cr
}%end twocolcode.


When a program is executed, the user is asked for the directory names of all
the files for which Pascal names appear in the program head.  The directory
names may be any TOPS-20 file name.  As a convenience, the names 
``{\tt TTY: }'' and ``{\tt LPT: }'' may be given as directory names (note
the colons); they are not actually files, but refer to the terminal screen
and line printer respectively.  Use of ``{\tt TTY: }'' as a directory name has
pitfalls; when the terminal is also being used as an input source by the
program, output may fail to appear on the terminal screen at the desired time.

        Two Pascal names of files may be implicit, unmentioned in the
program head:  {\tt OUTPUT} and {\tt INPUT}.  If no explicit Pascal file
name is given in a WRITE or WRITELN command, {\tt OUTPUT} is assumed:

\samecode{
WRITE($\Escr↓1,\ldotss,\Escr↓n$)⊗WRITE(OUTPUT,$\Escr↓1,\ldotss,\Escr↓n$)\cr
}%end samecode.

\noindent
If no explicit Pascal file name is given in a {\tt READ} command, {\tt INPUT}
is assumed:

\samecode{
READ($\Vscr↓1,\ldotss,\Vscr↓n$)⊗READ(INPUT,$\Vscr↓1,\ldotss,\Vscr↓n$)\cr
}%end samecode.

\noindent
When {\tt INPUT} and {\tt OUTPUT} are used as implicit Pascal names, the
corresponding directory names are also assumed to be {\tt INPUT} and
{\tt OUTPUT}.  For flexibility, it therefore is usually better to explicitly
name {\tt OUTPUT} and {\tt INPUT} in the program head.  When {\tt INPUT}
appears in the program head, it must be immediately followed by an
asterisk:
\wuncode{PROGRAM ${\Pscr}$ (INPUT*,OUTPUT)}

        When it is intended that a {\tt WRITE} command always send its 
results to the terminal screen, it is possible to use another implicit
Pascal name:{\tt ``TTY''} (unlike the correponding directory name, it
contains no colon).  Since such output leaves no permanent record, it is
typically used to inform and direct  the user.

%This is the end of INSERT A
\specialbegin{Conditional Commands} \sendindex{Conditional Commands}

     Pascal offers a type of command which tests whether some condition is true
or false, and executes one command or another accordingly.  The general form
of such commands is
\wuncode{IF $\Escr$ THEN $\Cscr ↓{1}$    ELSE $\Cscr ↓{2}$}
or
\wuncode{IF $\Escr$ THEN $\Cscr ↓{1}$}
where  $\Escr$  is a condition which can be tested.  If  $\Escr$  is true,        $\Cscr$$↓{1}$ is
executed; if  $\Escr$  is false, $\Cscr ↓{2}$ is executed in the first case, and nothing is
done in the second.

     The conditions \sendindex{conditions} may be of any of the forms

\twocolalign{
$\Escr ↓{1}$ = $\Escr ↓{2}$⊗\cr
$\Eone$ <> $\Etwo$⊗meaning $\Eone ≠ \Etwo$\cr
$\Escr ↓{1}$ < $\Escr ↓{2}$⊗\cr
$\Escr ↓{1}$ <= $\Escr ↓{2}$⊗(meaning $\Escr ↓{1} ≤ \Escr ↓{2}$)\cr
$\Escr ↓{1}$ > $\Escr ↓{2}$⊗\cr
$\Escr ↓{1}$ >= $\Escr ↓{2}$⊗(meaning $\Escr ↓{1} ≥ \Escr ↓{2}$)\cr
{\tt ODD(}$\Escr${\tt )}⊗(true if and only if the integer $\Escr$ is an odd number)\cr
}%end of twocolalign


Expressions such as these, having as values {\tt TRUE} or {\tt FALSE} rather than a number,
are called {\sl Boolean expressions} \sendindex{Boolean expressions} (after logician George Boole).

\example

     To print a table of squares, starting a new line after every fifth number,
we keep a variable with which we count how many squares have been printed on
the current line.  When the count reaches five, we start a new line and reset
the count to zero.

\startcode
        (heading, declarations)
        BEGIN
        COUNT:= 0;
        FOR I:= 1 TO 93 DO
           BEGIN
           WRITE(I*I);
           COUNT := COUNT+1;
           IF COUNT = 5 THEN
              BEGIN
              WRITELN;
              COUNT:= 0
              END
           END
        END.
\endcode

Notice the difference between {\tt =} and {\tt := ;} the first is used in conditions,
the second in assignment.

\example

     To print the picture of a square with a blank diagonal as shown below

\topoutput
         ****
        * ***
        ** **
        *** *
        ****
\botoutput


we could write

\startcode
        FOR R:=1 TO 5 DO   (* 5 ROWS *)
           BEGIN
           FOR C:=1 TO 5 DO   (* 5 CHARACTERS PER ROW *)
              IF R=C THEN
                 WRITE(' ')   (* ON THE DIAGONAL *)
              ELSE
                 WRITE('*');  (* NOT ON DIAGONAL *)
           WRITELN
           END
\endcode

\noindent
We could, in this case, have designed the program without conditional commands,
by viewing the pattern as a pair of triangles separated by a blank diagonal
line:

\startcode
        FOR R := 1 TO 5 DO
           BEGIN
           FOR C := 1 TO R-1 DO (*SKIPS IF R = 1*)
              WRITE('*');
           WRITE(' ');
           FOR C := 1 TO 5-R DO
              WRITE('*');
           WRITELN
           END
\endcode


\example

     In the game of chess, the rook is a piece which can move horizontally or
vertically, as far as desired (unless blocked by another piece).  We consider
the problem of drawing a diagram to show the rook at a specified place on the
chessboard, with all the squares to which the rook might move marked with
asterisks.  An example of such a diagram with the rook in the fourth row and
the third column is:

\topoutput
        ..*.....
        ..*.....
        ..*.....
        **R*****
        ..*.....
        ..*.....
        ..*.....
        ..*.....
\botoutput

\noindent
The large number of dots and asterisks suggests using an iteration, but since
they are intermixed there is little hope of writing separate iterations to
print dots and to print asterisks.  Instead, we iterate a conditional command
which, when executed, prints one character.  It chooses which character to
print in each position of the board by testing whether the position is occupied
or attacked by the rook.  The iterative structure of the program is

\startcode
        VAR R,C : INTEGER;         (* ROW AND COLUMN COUNTERS *)
            ROOKROW,ROOKCOL : INTEGER; (*  NOTE DESCRIPTIVE NAMES *)
        WRITE(TTY,'ENTER ROW ');
        BREAK(TTY);
        READ(TTY,ROOKROW);
        WRITE(TTY,'ENTER COLUMN ');
        BREAK(TTY);
        READ(TTY,ROOKCOL);
        FOR R:=1 STEP 1 UNTIL 8 DO    (* DRAW THE R-TH ROW *)
           BEGIN
           FOR C:=1 STEP 1 UNTIL 8 DO
               Print the correct character for column C of row R;
           WRITELN
           END
\endcode

\noindent
The printing command required above must print  ``{\tt R}'' if
{\tt R = ROOKROW} and 
{\tt C = ROOKCOL}; otherwise, it must print  ``{\tt *}'' on the rook's row  
{\tt (R = ROOKROW)} and on the rook's column  {\tt (C = ROOKCOL)}, and  
``{\tt .}'' elsewhere.  The printing command needed can be written:

\startcode
        IF R=ROOKROW THEN
                 (* PRINT ONE CHARACTER ON ROOK'S ROW *)
           IF C=ROOKCOL THEN WRITE('R')
           ELSE WRITE('*')
        ELSE     (* NOT ON ROOK'S ROW *)
           IF C=ROOKCOL THEN WRITE('*')
           ELSE WRITE('.')
\endcode

\noindent
It is essential to the above command that whenever it is executed, it prints
exactly one character.  The first condition chooses between two commands; each
of them, if executed, prints one character, as desired.  What would happen if
the above printing command were designed so that when  {\tt R = ROOKROW}
it would
print the entire 8 character row?  (If in doubt, try it.)

     Often, when a long series of actions is desired, but the actions are a
mixture of several different kinds, a programmer will write an iterative
command, iterating a conditional command which selects the appropriate action
for each value of the iteration variable.

     The grammar of conditional commands permits an apparently ambiguous
situation to arise.  Suppose we wanted to write a command to test variables
{\tt X} and {\tt Y}, printing {\tt  2}  if  {\tt X $≠$ 0}, printing  
{\tt 1}  if {\tt X = 0} and {\tt Y = 0},
and doing nothing if  {\tt X = 0} but {\tt Y $≠$ 0}.  We might write:

\startcode
        IF X = 0 THEN
           IF Y = 0 THEN WRITE(1)
        ELSE WRITE(2)
\endcode

\noindent
On the other hand, if we wanted to do nothing if  {\tt X $≠$ 0}, print  {\tt 1} if
{\tt X = 0}  and  {\tt Y = 0}, and print  {\tt 2}  if  {\tt X = 0}
and  {\tt Y $≠$ 0}, we might write

\startcode
        IF X = 0 THEN
           IF Y = 0 THEN WRITE(1)
           ELSE WRITE(2)
\endcode

\noindent
These are the same command, except for the spacing, which is not semantically
significant.  Yet the first supposedly prints  {\tt 2}  if  {\tt X $≠$ 0}, 
while the second does not print anything if  {\tt X $≠$ 0}. Which does the 
command mean?  It has the second meaning; where an {\tt ELSE} \sendindex{ELSE} 
could be matched with more than one {\tt IF}, \sendindex{IF} it is matched with 
the {\sl nearest} possible one.  We could force the {\tt ELSE} to
match the first {\tt IF}, as we intended in the first program, by ``hiding'' the second
{\tt IF} inside a compound statement:

\startcode
        IF X = 0 THEN
           BEGIN
           IF Y = 0 THEN WRITE(1)
           END
        ELSE WRITE(2)
\endcode

As a general rule, between any {\tt IF} and its matching {\tt ELSE}, there must be the same
number of {\tt IF}s as {\tt ELSE}s, not counting those ``hidden'' inside blocks.

\samecode{
IF $\Eone$ THEN⊗IF $\Eone$ THEN\cr
\quad IF $\Etwo$ THEN $\Cone$⊗\quad BEGIN\cr
\quad ELSE $\Ctwo$⊗\quad IF $\Etwo$ THEN $\Cone$\cr
⊗\quad ELSE $\Ctwo$\cr
⊗\quad END\cr
}%end of samecode

%This is INSERT M %for notes-after section on conditional commands
\sendnotes{FINALCHECK: eject inserted to eliminate widow 9/18.}
\sendnotes{DPB ==> RWF: The - signs in the Quad eqn prog are in math mode. Why?}
\vfill\eject
\example
\startcode
(*     SOLUTION OF A QUADRATIC EQUATION : A X X  +  B X  +  C          *)
PROGRAM QUADEQUATION ( INPUT*, OUTPUT ) ;
VAR  A, B, C,                           (*COEFFICIENTS OF EQUATION*)
     DISCR              :  REAL ;       (*DISCRIMINANT OF EQUATION *)
BEGIN
(* INPUT AND INITIAL OUTPUT *)
READ ( A, B, C ) ;  
WRITELN (' SOLUTION OF QUADRATIC EQUATION',
        A:8:4, ' Xβ2 + ', B:8:4, ' X + ', C:8:4, ' = 0.0000 ' ) ;
WRITELN ;
(* SOLUTION OF EQUATION*)
IF A = 0  THEN (* LINEAR EQUATION *)
    IF B = 0 THEN  (* DEGENERATE EQUATION C = 0 *)
        IF C = 0 THEN
            WRITELN (' INFINITELY MANY SOLUTIONS' )
        ELSE WRITELN (' NO SOLUTIONS' )
    ELSE (* REAL LINEAR EQUATION B X + C = 0 *)
         WRITELN (' SINGLE SOLUTION :',($-$C/B):8:4 )
ELSE (* PROPER QUADRATIC EQUATION *)
    BEGIN
    DISCR  := SQR(B)$-$4.0*A*C ;
    IF DISCR = 0 THEN
        WRITELN (' TWO IDENTICAL SOLUTIONS :',($-$B/(2.0*A)):8:4 )
    ELSE                              
        IF DISCR > 0 THEN
             BEGIN
             WRITELN (' TWO REAL SOLUTIONS :',
                  (($-$B$-$SQRT(DISCR))/(2.0*A)):8:4 );
             WRITELN ('                 ',
                  (($-$B+SQRT(DISCR))/(2.0*A)):8:4 )
             END
        ELSE
            BEGIN
            WRITELN (' TWO COMPLEX SOLUTIONS :',
               ($-$B/(2.0*A)):8:4,' + I ',(SQRT($-$DISCR)/(2.0*A)):8:4);
            WRITELN ('                       ',
               ($-$B/(2.0*A)):8:4,' - I ',(SQRT($-$DISCR)/2.0*A):8:4);
            END
    END
END.
\endcode
%This is INSERT K
%After conditionals
%part8.tex goes after conditionals
\example
This program reads the identification numbers and scores of one
hundred players in a tournament, and prints out the numbers and scores of
the two best players.  (In case of ties, it treats the first player as the
winner.)

\startcode
%p8e3 goes here
PROGRAM TOPTWO ;
VAR I, SCORE, BEST, SECOND, NUMBER, NUMBER1, NUMBER2: INTEGER;

BEGIN
BEST :=  - 1 ;  SECOND :=  - 1 ;
NUMBER1 := 0 ; NUMBER2 := 0 ;
FOR I := 1 TO 100 DO
    BEGIN
    READ (NUMBER , SCORE) ;
    IF SCORE > SECOND THEN
        IF SCORE > BEST THEN
            BEGIN
            SECOND := BEST ;
            BEST := SCORE ;
            NUMBER2 := NUMBER1 ;
            NUMBER1 := NUMBER ;
            END
        ELSE
            BEGIN
            SECOND := SCORE ;
            NUMBER2 := NUMBER
            END ;
    END ;
WRITELN(NUMBER1, BEST, NUMBER2, SECOND)
END.
\endcode
%This is the end of INSERT K
\exercise
In the game of chess, the queen is a piece which can move
horizontally, vertically, or diagonally.  Write a program to read, from the
terminal, the position of the queen (the number of the row and the number
of the column) and to print a diagram showing to which squares the queen can
move.  For example, such a diagram showing the possible queen moves from
row 4, column 3 is:
\endexercise

\topoutput
        ..*..*..
        *.*.*...
        .***....
        **Q*****
        .***....
        *.*.*...
        ..*..*..
        ..*...*.
\botoutput

\exercise
Write a program to keep track of a checking account.  Let the
initial balance be zero.  The first number read in is the total
number of checks and deposits.  The remaining data are the amounts of checks
(negative numbers) and deposits (positive numbers).  For each datum, the 
program should print the datum and the balance after processing the datum
by adding it to the balance.  Then change the program, to impose sevice 
charges of  \$0.05  per deposit and \$0.10  per check.
\endexercise

\exercise
Same as above, but waiving service charges on accounts which have
a balance of at least  \$300.00  after the deposit or check.
\endexercise

\exercise
Same as above, but taking into account overdrafts, according to
the following rules:

\bitem Service charges of  \$0.05  per deposit,  \$0.10  per check paid,
waived if the balance, before figuring in the service charge, is
at least \$300.

\bitem Penalty charge of \$3.00 per overdraft (a check that would, if cashed, 
       leave the balance negative, including service charges).

\bitem Checks which would leave a balance less than -\$50.00 are not honored
       (i.e. paid).  Take into account the effect of service charges in making
       this decision, but remember to charge only the penalty, and not the
       service charge, for a check which is not paid.


\noindent
Warning:  It is easy to make a mistake in programming the above policy.
Remember that the program must accept deposits even to overdrawn accounts, and
that the service charge on a check may overdraw the account.  Read the rules
{\sl very} carefully.  Try to think like a banker.
\endexercise